﻿/*
运用你所掌握的数据结构，设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作： 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中，则获取密钥的值（总是正数），否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在，则写入其数据值。当缓存容量达到上限时，它应该在写入新数据之前删除最近最少使用的数据值，从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作？

示例:

LRUCache cache = new LRUCache( 2 );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 该操作会使得密钥 2 作废
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 该操作会使得密钥 1 作废
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4
*/

#include "AllInc.h"

class LRUCache 
{
public:
	LRUCache(int capacity) 
	{
		cap = capacity;
	}

	int get(int key) 
	{
		auto it = ht.find(key);
		if (it == ht.end())
		{
			return -1;
		}
		int value = it->second->second;
		ls.erase(it->second);
		ls.push_front(make_pair(key, value));
		it->second = ls.begin();
		return value;
	}

	void put(int key, int value) 
	{
		auto it = ht.find(key);
		if (it == ht.end())
		{
			if (ls.size() >= cap)
			{
				ht.erase(ls.back().first);
				ls.pop_back();
			}
		}
		else
		{
			ls.erase(it->second);
		}
		ls.push_front(make_pair(key, value));
		ht[key] = ls.begin();
	}

private:
	int cap;
	list<pair<int, int>> ls;
	unordered_map<int, list<pair<int, int>>::iterator> ht;
};

//int main()
//{
//	LRUCache cache = LRUCache(2);
//
//	cache.put(1, 1);
//	cache.put(2, 2);
//	cache.get(1);       // 返回  1
//	cache.put(3, 3);    // 该操作会使得密钥 2 作废
//	cache.get(2);       // 返回 -1 (未找到)
//	cache.put(4, 4);    // 该操作会使得密钥 1 作废
//	cache.get(1);       // 返回 -1 (未找到)
//	cache.get(3);       // 返回  3
//	cache.get(4);       // 返回  4
//
//	return 0;
//}